package droid.mapViewer.primitives;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.microedition.khronos.opengles.GL10;

import droid.mapViewer.graphDrawers.Brush;
import droid.mapViewer.graphDrawers.Pen;
import droid.mapViewer.utils.Point;
import droid.mapViewer.utils.PointsFloatBuffer;

public class Region implements IPrimitive {
	private List<PointsFloatBuffer> simpleRegions = new ArrayList<PointsFloatBuffer>();
	private Pen pen;
	private Brush brush;
	FloatBuffer bbox;
	
	Region(List<SimpleRegion> simpleRegions) {
		pen = simpleRegions.get(simpleRegions.size() - 1).getPen();
		brush = simpleRegions.get(simpleRegions.size() - 1).getBrush();
		Point center = simpleRegions.get(simpleRegions.size() - 1).getCenter();
		Iterator<SimpleRegion> i = simpleRegions.iterator();
		while (i.hasNext()) {
			this.simpleRegions.add(PointsFloatBuffer.convertToFloatBuffer(i.next().getPoints(), center));
		}
	/*	ByteBuffer bb = ByteBuffer.allocateDirect(12 * 6);
		bb.order(ByteOrder.nativeOrder());
		bbox = bb.asFloatBuffer();
		float minX = -0.7f;//simpleRegions.get(i).getMin(Point.X_ID);
		float minY = -0.5f;//simpleRegions.get(i).getMin(Point.Y_ID);
		float maxX = 1f;//simpleRegions.get(i).getMax(Point.X_ID);
		float maxY = 1.2f;//simpleRegions.get(i).getMax(Point.Y_ID);
		bbox.put(0);
		bbox.put(0);
		bbox.put(0);
		bbox.put(minX);
		bbox.put(minY);
		bbox.put(z);
		bbox.put(minX);
		bbox.put(maxY);
		bbox.put(z);
		bbox.put(maxX);
		bbox.put(maxY);
		bbox.put(z);
		bbox.put(maxX);
		bbox.put(minY);
		bbox.put(z);
		bbox.put(minX);
		bbox.put(minY);
		bbox.put(z);
		bbox.position(0);*/
	}
	
	void drawP1(GL10 gl) {
		List<Point> points = new ArrayList<Point>();
		gl.glColor4f(1f, 0, 0, 0);
		points.add(new Point(0f, 0f));
		points.add(new Point(1.0f, 1.0f));
		points.add(new Point(-1.0f, 1.0f));
		points.add(new Point(-1.0f, -1.0f));
		points.add(new Point(1.0f, -1.0f));
		points.add(new Point(1.0f, 1.0f));
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, PointsFloatBuffer.convertToFloatBuffer(points, null).getBuffer());
		gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, 6);
	}
	
	void drawP2(GL10 gl) {
		List<Point> points = new ArrayList<Point>();
		gl.glColor4f(0, 1f, 0, 0);
		points.add(new Point(0f, 1.5f));
		points.add(new Point(-1.5f, -1.5f));
		points.add(new Point(1.5f, -1.5f));
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, PointsFloatBuffer.convertToFloatBuffer(points, null).getBuffer());
		gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
	}
	
	void drawP3(GL10 gl) {
		List<Point> points = new ArrayList<Point>();
		gl.glColor4f(0, 0, 1f, 0);
		points.add(new Point(0f, 2f));
		points.add(new Point(-2f, -2f));
		points.add(new Point(2f, -2f));
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, PointsFloatBuffer.convertToFloatBuffer(points, null).getBuffer());
		gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
	}
	
	void drawPrim(GL10 gl)
	{
		gl.glStencilFunc(GL10.GL_ALWAYS, 2, 1);
		gl.glStencilOp(GL10.GL_KEEP, GL10.GL_REPLACE, GL10.GL_KEEP);
		
		drawP1(gl);
		
		gl.glStencilFunc(GL10.GL_NEVER, 1, 1);
		gl.glStencilOp(GL10.GL_REPLACE, GL10.GL_KEEP, GL10.GL_KEEP);
		
		drawP2(gl);

		gl.glStencilFunc(GL10.GL_EQUAL, 2, 1);
		gl.glStencilOp(GL10.GL_KEEP, GL10.GL_KEEP, GL10.GL_KEEP);
		
		drawP3(gl);
	}
	public void draw(GL10 gl) {
		gl.glEnable(GL10.GL_STENCIL_TEST);
		gl.glClearStencil(0);
		gl.glStencilMask(1);
		gl.glClear(GL10.GL_DEPTH_BUFFER_BIT | GL10.GL_STENCIL_BUFFER_BIT); 
		drawPrim(gl);
		gl.glDisable(GL10.GL_STENCIL_TEST);
		
		
/*		List<Point> points = new ArrayList<Point>();
		
		pen.applayToScene(gl);
		gl.glEnable(GL10.GL_STENCIL_TEST);
		gl.glClearStencil(0);
		gl.glStencilMask(1);
		
	    gl.glClear(GL10.GL_DEPTH_BUFFER_BIT | GL10.GL_STENCIL_BUFFER_BIT); 
	    gl.glStencilFunc(GL10.GL_ALWAYS, 2, 1);
	    gl.glStencilOp(GL10.GL_KEEP, GL10.GL_REPLACE, GL10.GL_KEEP);
	    gl.glColor4f(1f, 0, 0, 0);
/*		points.add(new Point(-1,-1));
		points.add(new Point(1,1));
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, PointsFloatBuffer.convertToFloatBuffer(points, null).getBuffer());
		gl.glDrawArrays(GL10.GL_LINES, 0, 2);
		points.clear();
		points.add(new Point(-1,-1));
		points.add(new Point(0,1));
		points.add(new Point(1,-1));
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, PointsFloatBuffer.convertToFloatBuffer(points, null).getBuffer());
		gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
		
		gl.glStencilFunc(GL10.GL_NEVER, 1, 1);
		gl.glStencilOp(GL10.GL_REPLACE, GL10.GL_KEEP, GL10.GL_KEEP);
		gl.glColor4f(0, 1f, 0, 0);
		FloatBuffer aa = PointsFloatBuffer.convertToFloatBuffer(points, null).getRectBuffer();
		points.clear();
		points.add(new Point(-0.5f,-0.5f));
		points.add(new Point(0,0.5f));
		points.add(new Point(0.5f,-0.5f));
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, PointsFloatBuffer.convertToFloatBuffer(points, null).getBuffer());
		gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
		
		gl.glStencilFunc(GL10.GL_EQUAL, 2, 1);
		gl.glStencilOp(GL10.GL_KEEP, GL10.GL_KEEP, GL10.GL_KEEP);
		gl.glColor4f(0, 0, 1f, 0);
		
	    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, aa);
		gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, 6);
		gl.glDisable(GL10.GL_STENCIL_TEST);
		*/
	/*	pen.applayToScene(gl);
		Iterator<PointsFloatBuffer> i = simpleRegions.iterator();
		 gl.glColor4f(0, 1f, 0, 0);
		gl.glClearStencil(0);
	    gl.glClear(GL10.GL_STENCIL_BUFFER_BIT); 
	    gl.glStencilOp(GL10.GL_INVERT, GL10.GL_INVERT, GL10.GL_INVERT);
		//gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT | GL10.GL_STENCIL_BUFFER_BIT);
		//gl.glEnable(GL10.GL_STENCIL_TEST);
		while (i.hasNext()) { // Цикл по всем многоугольникам
			PointsFloatBuffer fb = i.next();
	//		gl.glStencilFunc(GL10.GL_ALWAYS, 0, 1);
	//		gl.glStencilOp(GL10.GL_KEEP, GL10.GL_KEEP, GL10.GL_INVERT);
	//		gl.glColorMask(false, false, false, false);
		    // Рисуем многоугольник с помощью три фана
			gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
			
			gl.glVertexPointer(3, GL10.GL_FLOAT, 0, fb.getBuffer());
			gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, fb.count());
			
			gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	//		gl.glStencilFunc(GL10.GL_NOTEQUAL, 0, 1);
	//	    gl.glStencilOp(GL10.GL_KEEP, GL10.GL_KEEP, GL10.GL_ZERO);
	//	    gl.glColorMask(true, true, true, true);
	//	    gl.glColor4f(0, 1f, 0, 0); // Цвет многоугольника
		    // Теперь рисуем ббокс этого многоугольника
		    
		 	
		}
		gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
	//    gl.glClear(GL10.GL_COLOR_BUFFER_BIT); 
	    gl.glColor4f(0, 1f, 0, 0);
	    gl.glEnable(GL10.GL_STENCIL_TEST);
	    gl.glStencilFunc(GL10.GL_NOTEQUAL, 0, 0xFF);
		
		
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
	 	gl.glVertexPointer(3, GL10.GL_FLOAT, 0, simpleRegions.get(0).getRectBuffer());
	 	gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, 6);
	 	gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glDisable(GL10.GL_STENCIL_TEST);
	*/	
		
/*		

	    // Рисуем вееры на каждый subpath.
	    // Конечно же, для этого лучше задействовать glDrawElements(GL_TRIANGLES...) 
	    float xc = 0;
	    float yc = 0;
	    for(i = 0; i < path.GetNumSubpaths(); i++)
	    {
	        const SubpathType& sp = path.GetSubpath(i);
	        for(j = 0; j < sp.GetNumVertices(); j++)
	        {
	            const VertexType& v1 = j ? sp.GetVertex(j - 1) : sp.GetLastVertex();
	            const VertexType& v2 = sp.GetVertex(j);
	            glBegin(GL_TRIANGLES);
	            glVertex2f(xc, yc);
	            glVertex2f(v1.x, v1.y);
	            glVertex2f(v2.x, v2.y);
	            glEnd();
	        }
	    }

	    // Далее включаем STENCIL_TEST и рисуем два треугольника, 
	    // покрывающие bounding box. Для простоты возьмем во все окно.
	    gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
	    gl.glClear(GL10.GL_COLOR_BUFFER_BIT); 
	    gl.glColor4f(0, 1f, 0, 0);
	    gl.glEnable(GL_STENCIL_TEST);
	    gl.glStencilFunc(GL10.GL_NOTEQUAL, 0, 0xFF);
	    glBegin(GL_TRIANGLES);
	    glVertex2f(-1, -1);
	    glVertex2f( 1, -1);
	    glVertex2f( 1,  1);
	    glVertex2f(-1, -1);
	    glVertex2f( 1,  1);
	    glVertex2f(-1,  1);
	    glEnd();
	}
	
	/**
	 * Подготавливаем буффер для вывода многоугольника.
	 * @param size - количество точек многоугольника
	 * @return буффер
	 */
	/*private FloatBuffer getBuffer(int index) {
		int size = simpleRegions.get(index).size();
		ByteBuffer bb = ByteBuffer.allocateDirect(12 * size);
		bb.order(ByteOrder.nativeOrder());
		//TODO Не забываем, что в полигоне в файле MIF первая и последняя точка совпадают
		FloatBuffer simpleRegion = bb.asFloatBuffer();
		for (int i=0; i<size; i++) {
			simpleRegion.put(simpleRegions.get(index).getPoint(i).getx());
			simpleRegion.put(simpleRegions.get(index).getPoint(i).gety());
			simpleRegion.put(z);
		}
		simpleRegion.position(0);
		return simpleRegion;*/
	}
}
